import logging

# 导入操作系统相关模块
import os

# from dotenv import load_dotenv

# # # 加载环境变量文件
# load_dotenv()

# 导入pprint用于美观打印数据
from pprint import pprint

# 导入类型提示相关类型
from typing import Optional, Dict

# 从DrissionPage库导入ChromiumOptions和Chromium类
from DrissionPage import ChromiumOptions, Chromium

# 配置日志输出格式和级别
logging.basicConfig(
    level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s"
)

# 获取以当前模块名为名称的logger对象
logger = logging.getLogger(__name__)

# 从环境变量获取Chrome浏览器路径，若未设置则使用默认路径
CHROME_PATH = os.getenv(
    "CHROME_PATH",
    r"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome --remote-debugging-port=9223",
)
print("CHROME_PATH", CHROME_PATH)

# 从环境变量获取搜索关键词，若未设置则默认为'AI前端'
KEYWORD = os.getenv("SEARCH_KEYWORD", "AI前端")


# 定义BossSpider爬虫类
class BossSpider:
    # 初始化方法
    def __init__(self):
        # 保存Chrome浏览器路径
        self.chrome_path = CHROME_PATH
        # 初始化浏览器
        self._setup_browser()

    # 浏览器初始化方法
    def _setup_browser(self):
        try:
            # 设置浏览器路径并保存配置
            ChromiumOptions().set_browser_path(self.chrome_path).save()
            # 创建Chromium浏览器对象
            self.browser = Chromium()
            # 获取最新的标签页对象
            self.tab = self.browser.latest_tab
        except Exception as e:
            # 浏览器初始化失败时记录错误日志
            logger.error(f"浏览器初始化失败: {e}")
            # 抛出异常
            raise

    # 获取职位详情的方法，参数为职位卡片对象
    def get_job_details(self, card) -> Optional[Dict]:
        try:
            # 获取职位名称
            job_name = card.ele(".job-name").text
            # 获取公司名称
            company = card.ele("@|class=boss-info@|class=boss-name").text
            # 获取城市信息
            city = card.ele(".company-location").text
            # 获取职位标签列表
            job_info = card.ele(".tag-list")
            # 获取所有标签元素
            job_infos = job_info.eles("tag:li")
            # 获取工作经验
            experience = job_infos[0].text if len(job_infos) > 0 else ""
            # 获取学历要求
            education = job_infos[1].text if len(job_infos) > 1 else ""
            # 返回职位详情字典
            return {
                "job_name": job_name,
                "company": company,
                "city": city,
                "experience": experience,
                "education": education,
            }
        except Exception as e:
            # 获取职位详情失败时记录错误日志
            logger.error(f"获取职位详情失败: {e}")
            # 返回None
            return None

    # 爬取职位信息的方法
    def crawl_jobs(self):
        # 记录开始爬取的日志
        logger.info("开始爬取职位信息")
        # 打开职位搜索页面
        self.tab.get(f"https://www.zhipin.com/web/geek/jobs?query={KEYWORD}")
        try:
            # 等待职位卡片元素加载完成，超时时间10秒
            self.tab.wait.eles_loaded(".job-card-box", timeout=10)
        except Exception as e:
            # 等待超时时记录错误日志
            logger.error(f"等待职位卡片元素超时: {e}")
            # 直接返回
        # 获取所有职位卡片元素
        cards = self.tab.eles(".job-card-box")
        # 遍历每个职位卡片
        for card in cards:
            # 获取职位详情
            job_data = self.get_job_details(card)
            # 打印职位详情
            pprint(job_data)


# 定义运行爬虫的函数
def run_spider():
    try:
        # 创建BossSpider实例
        spider = BossSpider()
        # 调用爬取方法
        spider.crawl_jobs()
    except Exception as e:
        # 捕获异常并记录错误日志
        logger.error(f"爬虫运行失败: {e}")
        # 重新抛出异常
        raise


# 判断是否为主程序入口
if __name__ == "__main__":
    # 运行爬虫
    run_spider()
